#!/usr/bin/python
# -*- coding: utf-8 -*-
# File communication_layer.py

import communication
import threading
import Queue
import time
import const

class CommunicationLayer( threading.Thread ):
    """Communication Layer of the Rotob

    This class provide a communication unrelated impelementation
    Use communication interface to recieve and send messages.
    In other word it's just a relay between application and communication
    Now it's run in thread communicate to other layer with Queue 
    """

    def __init__( self, output_queue, input_queue, stop_flag ):
        threading.Thread.__init__( self )
        self.output_queue = output_queue
        self.input_queue = input_queue
        self.stop_flag = stop_flag
        self.communication = communication.Communication()
        self.message_buffer = []

    def run( self ):
        self.communication.start() 

        while True:
            if self.stop_flag[0]:
                break

            self.__send_message()

            self.__receive_message()

            time.sleep( 0.002 )

        self.communication.stop()

    def __send_message( self ):
        """Send message in the input_queue to server"""

        while True:
            try:
                message = self.input_queue.get( 0 )
            except Queue.Empty:
                break
            else:
                self.communication.send( message )

    def __receive_message( self ):
        """Receive message and put them into the output_queue"""

        length = len( self.message_buffer )
        self.message_buffer[ length: ] = self.communication.receive()
        length = len( self.message_buffer )
        i = 0
        while i < length:
            message = self.message_buffer.pop( 0 )
            try:
                self.output_queue.put( message, 0 )
            except Queue.Full:
                self.message_buffer.insert( 0, message )
                break
            else:
                i += 1

class TestReader( threading.Thread ):
    """A Test Reader, NOT USE"""

    def __init__( self, queue, stop_flag ):
        threading.Thread.__init__( self )
        self.queue = queue
        self.stop_flag = stop_flag

    def run( self ):
        while True:
            if self.stop_flag[0]:
                break

            try:
                message = self.queue.get( 0 )
            except Queue.Empty:
                continue
            else:
                print message

        print 'TestReader stop'

def main():
    input_queue = Queue.Queue(100)
    output_queue = Queue.Queue(100)
    stop_flag = [0]

    reader = TestReader( output_queue, stop_flag )
    comm = CommunicationLayer( output_queue, input_queue, stop_flag )

    print 'start threading'
    comm.start()
    reader.start()
    print 'threading start'

    for i in xrange(10):
        time.sleep( 1 )
        message = { 'type' : const.MESSAGE,
                    'text' : 'hello',
                    'to' : 'zhaopengwei1014@gmail.com'}
        input_queue.put( message, 0 )

    print 'I am here'
    stop_flag[0] = 1
    print 'All Done'

if __name__ == '__main__':
    main()

# End of communication_layer.py
